#pragma once
#include"../../LibDGGSBase/DGGSDefine.hpp"
_NNU_DGGS_BEGIN
    using namespace Base;
    namespace Kernel::Projection
    {
        /// <summary>
        /// 三角面坐标
        /// </summary>
        struct SurfacePt
        {
            double x;
            double y;
            int triangle = -1;
        };


        /// <summary>
        /// ISEA
        /// </summary>
        class ISEA
        {
            /******************************************************正二十面体三角形参数***********************************************************/

        private:
            //菱形块编号 三角形编号 邻接三角形序号 keep X平移量 Y平移量 旋转系数
            double *_vertTable = nullptr;
            double *_triParaments = nullptr;

        public:
            /// <summary>
            /// 初始化
            /// </summary>
            void init();
            /// <summary>
            /// 释放
            /// </summary>
            void release();


            /********************************************************格网编码转经纬度坐标*******************************************************/
#pragma region RC2LBCenter
        public:
            /// <summary>
            /// 行列编码转经纬度
            /// </summary>
             void RC2LBCenter(DGGSGridType topo, int basePartition, long long int row, long long int col, int level, double &lon, double &lat);

        private:
            /// <summary>
            /// 计算两点在投影平面上的距离
            /// </summary>
             double getSnyderDist(Pt2D &g1, const Pt2D &g2, bool rads);

            /// <summary>
            /// 计算格子落在顶点坐标系的哪个三角形上
            /// </summary>
             int calSubtriangle(const double &x, const double &y);

            /// <summary>
            /// 行列号转格网坐标
            /// </summary>
            void invQuantify(DGGSGridType topo, long long int i, long long int j, double *add);

            /// <summary>
            /// 施耐德反算
            /// </summary>
             void snyderInv(double *xyCoord, int triangle, double *lonlatCoord);

            /// <summary>
            /// 编码转经纬度
            /// </summary>
             void convertTypeAddress(double *cent, double scaleFac, double *trans, double rotDeg, int quadNum,
                                    double *result);

#pragma endregion
            /********************************************************经纬度坐标转格网编码*******************************************************/
#pragma region LB2RC
        public:
            /// <summary>
            /// 经纬度转行列坐标
            /// </summary>
             bool LB2RC(double lon, double lat, int level, DGGSGridType topo, int &basePartition, long long int &row, long long int &col);

        private:

            /// <summary>
            /// 球面坐标转平面坐标
            /// </summary>
             Pt2D sphere2Plane(const Pt2D &geoVect, int nTri);

            /// <summary>
            /// 计算点属于哪个三角面
            /// </summary>
             int computeSubTriangle(const Pt2D &pt);

            /// <summary>
            /// 施奈德正算
            /// </summary>
             SurfacePt snyderFwd(const Pt2D &ll);

            /// <summary>
            /// 旋转算法
            /// </summary>
             void rotate(double degrees, Pt2D &point);

            /// <summary>
            /// 缩放算法
            /// </summary>
             Pt2D scale(const Pt2D addIn, double scaleFac);

            /// <summary>
            /// 经纬度转行列坐标
            /// </summary>
             int planeCoords2RC(const SurfacePt &gridpt, double scaleFac, Pt2D trans, DGGSGridType topo, RCPt2D &result);

            /// <summary>
            /// 菱形格子量化坐标
            /// </summary>
             RCPt2D rhoQuantify(const Pt2D &point);

            /// <summary>
            /// 三角形格子量化坐标
            /// </summary>
             RCPt2D triQuantify(const Pt2D &point);

            /// <summary>
            /// 六边形格子量化坐标
            /// </summary>
             RCPt2D HexQuantify(const Pt2D &point);

#pragma endregion
            /********************************************************格点编码转经纬度坐标*******************************************************/
#pragma region RC2LBVertex
        public:
            bool RC2LBVertex(int basePartition, long long int row, long long int col, int level, DGGSGridType topo, double*& result);
#pragma endregion
        };

    }
_NNU_DGGS_END